/*
 * Copyright (c) 2025 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License")
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "secure_element_common.h"
#include <securec.h>
#include "common_utils.h"
#include "loghelper.h"
#include "reader.h"

namespace OHOS {
namespace SE {
namespace OMAPI {
int32_t Convert2CJErrorCode(ErrorCode errcode)
{
    switch (errcode) {
        case ErrorCode::SE_ILLEGAL_STATE_ERROR:
            return CJ_ILLEGAL_STATE_ERR;
        case ErrorCode::SE_ILLEGAL_PARAMETER_ERROR:
            return CJ_ILLEGAL_ELEMENT_ERR;
        case ErrorCode::SE_SECURITY_ERROR:
            return CJ_SECURITY_ERR;
        case ErrorCode::SE_IO_ERROR:
            return CJ_IO_ERR;
        default:
            return CJ_UNSUPPORTED_ERR;
    }
    return CJ_UNSUPPORTED_ERR;
}

CArrI32 ConvertString2Arr(std::string srcValue)
{
    CArrI32 arr;
    uint32_t strLength = srcValue.length();
    if (strLength % HEX_BYTE_LEN != 0) {
        srcValue = '0' + srcValue;
        strLength++;
    }
    int64_t size = static_cast<int64_t>(strLength / HEX_BYTE_LEN);
    arr.size = size;
    int32_t mallocSize = static_cast<int32_t>(sizeof(int32_t) * size);
    if (mallocSize <= 0 || mallocSize > static_cast<int32_t>(sizeof(int32_t) * MAX_MEM_MALLOC_SIZE)) {
        return CArrI32();
    }
    auto head = static_cast<int32_t *>(malloc(mallocSize));
    if (head == nullptr) {
        return CArrI32();
    }
    arr.head = head;
    uint32_t srcIntValue = 0;
    uint32_t strIter = 0;
    int64_t iter = 0;
    for (; strIter < strLength && iter < size; strIter += HEX_BYTE_LEN, iter++) {
        std::string oneByte = srcValue.substr(strIter, HEX_BYTE_LEN);
        if (sscanf_s(oneByte.c_str(), "%x", &srcIntValue) <= 0) {
            ErrorLog("ConvertString2Arr, sscanf_s failed.");
            free(head);
            return CArrI32();
        }
        int32_t res = static_cast<int32_t>(srcIntValue & 0xFF);
        head[iter] = res;
    }
    return arr;
}

std::string ConvertArr2String(CArrI32 aid)
{
    std::string res = "";
    if (aid.head == nullptr || aid.size == 0) {
        return res;
    }
    const std::string hexKeys = "0123456789ABCDEF";
    for (int64_t i = 0; i < aid.size; i++) {
        auto value = static_cast<uint32_t>(aid.head[i]);
        res.push_back(hexKeys[(value & 0xF0) >> HALF_BYTE_SHIFT]);
        res.push_back(hexKeys[value & 0x0F]);
    }
    return res;
}

char *MallocCString(const std::string &origin)
{
    if (origin.empty()) {
        return nullptr;
    }
    auto len = origin.length() + 1;
    char *res = static_cast<char *>(malloc(sizeof(char) * len));
    if (res == nullptr) {
        return nullptr;
    }
    return std::char_traits<char>::copy(res, origin.c_str(), len);
}

int32_t IsSupportOpenBasicChannel(std::weak_ptr<Session> session)
{
    std::string readerName{};
    std::weak_ptr<Reader> reader{};
    if (session.expired()) {
        return SE_ILLEGAL_STATE_ERROR;
    }
    session.lock()->GetReader(reader);
    if (reader.expired()) {
        return SE_ILLEGAL_STATE_ERROR;
    }
    reader.lock()->GetName(readerName);
    if (readerName.compare(SE_NAME_SIM) == 0 || readerName.compare(SE_NAME_SIM2) == 0) {
        return SE_IO_ERROR;
    }
    return SE_SUCCESS;
}
}  // namespace OMAPI
}  // namespace SE
}  // namespace OHOS